import SockJS from 'sockjs-client'
import { Stomp } from '@stomp/stompjs'
import { ElNotification } from 'element-plus'

// 确保全局变量存在
if (typeof global === 'undefined') {
  window.global = window
}

class WebSocketManager {
  constructor() {
    this.stompClient = null
    this.connected = false
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = 5
    this.reconnectInterval = 5000
    this.subscriptions = new Map()
    this.messageHandlers = new Map()
  }

  /**
   * 连接WebSocket
   */
  connect(token) {
    if (this.connected) {
      console.log('WebSocket已连接')
      return Promise.resolve()
    }

    return new Promise((resolve, reject) => {
      try {
        // 创建SockJS连接
        const socket = new SockJS('/ws')
        this.stompClient = Stomp.over(socket)

        // 设置调试信息（生产环境可关闭）
        this.stompClient.debug = (str) => {
          console.log('STOMP: ' + str)
        }

        // 连接配置
        const connectHeaders = {}
        if (token) {
          connectHeaders['Authorization'] = `Bearer ${token}`
        }

        // 建立连接
        this.stompClient.connect(
          connectHeaders,
          (frame) => {
            console.log('WebSocket连接成功:', frame)
            this.connected = true
            this.reconnectAttempts = 0
            
            // 订阅通知频道
            this.subscribeToNotifications()
            
            resolve()
          },
          (error) => {
            console.error('WebSocket连接失败:', error)
            this.connected = false
            this.handleReconnect()
            reject(error)
          }
        )
      } catch (error) {
        console.error('WebSocket连接异常:', error)
        reject(error)
      }
    })
  }

  /**
   * 订阅通知频道
   */
  subscribeToNotifications() {
    if (!this.stompClient || !this.connected) {
      console.warn('WebSocket未连接，无法订阅')
      return
    }

    // 订阅广播通知
    const broadcastSub = this.stompClient.subscribe('/topic/notifications', (message) => {
      const notification = JSON.parse(message.body)
      this.handleNotification(notification)
    })
    this.subscriptions.set('broadcast', broadcastSub)

    // 订阅私人通知（如果有用户ID）
    const userId = this.getCurrentUserId()
    if (userId) {
      const privateSub = this.stompClient.subscribe(`/user/${userId}/queue/notifications`, (message) => {
        const notification = JSON.parse(message.body)
        this.handleNotification(notification)
      })
      this.subscriptions.set('private', privateSub)
    }

    console.log('已订阅通知频道')
  }

  /**
   * 处理接收到的通知
   */
  handleNotification(notification) {
    console.log('收到通知:', notification)

    // 显示通知
    this.showNotification(notification)

    // 触发自定义处理器
    const handlers = this.messageHandlers.get(notification.type) || []
    handlers.forEach(handler => {
      try {
        handler(notification)
      } catch (error) {
        console.error('通知处理器执行失败:', error)
      }
    })
  }

  /**
   * 显示通知
   */
  showNotification(notification) {
    const notificationConfig = {
      title: notification.title || '新通知',
      message: notification.content || '',
      type: this.getNotificationType(notification.level),
      duration: 5000,
      showClose: true
    }

    // 根据消息类型设置不同的样式
    if (notification.type === 'NOTICE') {
      notificationConfig.type = 'info'
    } else if (notification.type === 'SYSTEM') {
      notificationConfig.type = notification.level || 'info'
    }

    ElNotification(notificationConfig)
  }

  /**
   * 获取通知类型
   */
  getNotificationType(level) {
    const typeMap = {
      'success': 'success',
      'info': 'info',
      'warning': 'warning',
      'error': 'error'
    }
    return typeMap[level] || 'info'
  }

  /**
   * 发送消息
   */
  sendMessage(destination, message) {
    if (!this.stompClient || !this.connected) {
      console.warn('WebSocket未连接，无法发送消息')
      return false
    }

    try {
      this.stompClient.send(destination, {}, JSON.stringify(message))
      return true
    } catch (error) {
      console.error('发送消息失败:', error)
      return false
    }
  }

  /**
   * 发送心跳
   */
  sendHeartbeat() {
    this.sendMessage('/app/heartbeat', { type: 'heartbeat', timestamp: new Date().getTime() })
  }

  /**
   * 添加消息处理器
   */
  addMessageHandler(type, handler) {
    if (!this.messageHandlers.has(type)) {
      this.messageHandlers.set(type, [])
    }
    this.messageHandlers.get(type).push(handler)
  }

  /**
   * 移除消息处理器
   */
  removeMessageHandler(type, handler) {
    const handlers = this.messageHandlers.get(type)
    if (handlers) {
      const index = handlers.indexOf(handler)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    }
  }

  /**
   * 断开连接
   */
  disconnect() {
    if (this.stompClient && this.connected) {
      // 取消所有订阅
      this.subscriptions.forEach(subscription => {
        subscription.unsubscribe()
      })
      this.subscriptions.clear()

      // 断开连接
      this.stompClient.disconnect(() => {
        console.log('WebSocket连接已断开')
      })
      
      this.connected = false
      this.stompClient = null
    }
  }

  /**
   * 重连处理
   */
  handleReconnect() {
    if (this.reconnectAttempts < this.maxReconnectAttempts) {
      this.reconnectAttempts++
      console.log(`尝试重连WebSocket (${this.reconnectAttempts}/${this.maxReconnectAttempts})`)
      
      setTimeout(() => {
        const token = localStorage.getItem('token')
        this.connect(token).catch(error => {
          console.error('重连失败:', error)
        })
      }, this.reconnectInterval)
    } else {
      console.error('WebSocket重连次数已达上限')
      ElNotification({
        title: '连接失败',
        message: '无法连接到服务器，请刷新页面重试',
        type: 'error',
        duration: 0
      })
    }
  }

  /**
   * 获取当前用户ID
   */
  getCurrentUserId() {
    try {
      const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
      return userInfo.id
    } catch {
      return null
    }
  }

  /**
   * 检查连接状态
   */
  isConnected() {
    return this.connected && this.stompClient && this.stompClient.connected
  }
}

// 创建全局实例
const webSocketManager = new WebSocketManager()

export default webSocketManager
